package com.ruyuan.eshop.diplomacy.manager.common.db;

import com.google.common.collect.Sets;
import com.ruyuan.eshop.diplomacy.domain.dao.DiplomacyDAO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.ruyuan.eshop.common.constants.diplomacy.BaseConstants.LONG_FIVE_MINUTES;
import static com.ruyuan.eshop.common.utils.diplomacy.NumberUtils.getInteger;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;

/**
 * redis(string)数据源抽象类
 *
 * @author zhonghuashishan
 */
@Slf4j
public abstract class AbstractRedisStringDatabase<DO> implements RedisStringDatabase<DO> {

    @Resource
    protected DiplomacyDAO diplomacyDAO;

    /**
     * 5分钟内单表变更数据主键ID集合
     *
     * @param tableName 需要查询的表名
     * @return java.util.Optional<java.util.Set<java.lang.Integer>>
     * @author zhonghuashishan
     */
    private Optional<Set<Integer>> getSingleTableUpdateIdSet(String tableName) {
        // 获取最近5分钟时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String beforeDate = simpleDateFormat.format(new Date(System.currentTimeMillis() - LONG_FIVE_MINUTES));

        // 获取sql
        String sql = "SELECT ID FROM " + tableName + " WHERE UPDATE_TIME>'" + beforeDate + "'";
        List<Map<String, Object>> mapList = diplomacyDAO.select(sql);
        if (CollectionUtils.isEmpty(mapList)) {
            return Optional.empty();
        }
        Set<Integer> idSet = mapList.stream().map(fieldMap -> getInteger(fieldMap.get("ID"))).collect(toSet());
        return Optional.of(idSet);
    }

    /**
     * 获取表变更主键ID集合
     *
     * @param
     * @return java.util.Optional<java.util.Set<java.lang.Integer>>
     * @author zhonghuashishan
     */
    @Override
    public Optional<Set<Integer>> getTableUpdateIdSet() {
        Set<Integer> resultSet = Sets.newHashSet();
        Set<String> tableNameSet = getTableNameSet();
        for (String tableName : tableNameSet) {
            Optional<Set<Integer>> singleTableIdSetOpt = getSingleTableUpdateIdSet(tableName);
            if (!singleTableIdSetOpt.isPresent()) {
                continue;
            }

            Optional<Set<Integer>> primaryIdSetOpt = getTableIdSetByRelationTableIdSet(tableName, singleTableIdSetOpt.get());
            if (primaryIdSetOpt.isPresent()) {
                resultSet.addAll(primaryIdSetOpt.get());
            }
        }
        return CollectionUtils.isEmpty(resultSet) ? Optional.empty() : Optional.of(resultSet);
    }

    /**
     * 获取单表所有主键ID集合
     *
     * @param
     * @return java.util.Optional<java.util.List<java.lang.Integer>>
     * @author zhonghuashishan
     */
    @Override
    public Optional<List<Integer>> getTableAllIdList() {
        String sql = "SELECT ID FROM " + getTableName();
        List<Map<String, Object>> mapList = diplomacyDAO.select(sql);
        if (CollectionUtils.isEmpty(mapList)) {
            return Optional.empty();
        }
        List<Integer> idSet = mapList.stream().map(fieldMap -> getInteger(fieldMap.get("ID"))).collect(toList());
        return Optional.of(idSet);
    }

    /**
     * 获取主表ID集合（关联表变更需要查询主表）
     *
     * @param relationTableName     关联表名
     * @param relationTableIdSet    关联表主键集合
     * @return java.util.Optional<java.util.Set<java.lang.Integer>>
     * @author zhonghuashishan
     */
    @Override
    public Optional<Set<Integer>> getTableIdSetByRelationTableIdSet(String relationTableName, Set<Integer> relationTableIdSet) {
        if (relationTableName.equals(getTableName())) {
            return Optional.ofNullable(relationTableIdSet);
        }
        throw new UnsupportedOperationException();
    }

}
